/*----------------------------------------------------------------------------
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
------------------------------------------------------------------------------

Lisence: GNU GPL
Project Name:Meteo (PMCS)
Author:Dimitrios Kanellopoulos
Email:jimmykane9 (AT) gmail (DOT) com
Version:3 -Initial Release 
Date: 18/12/09
Why: Exam exersice in Paralle Computing (parallel@oslab.teipir.gr)
Synopsis: This programm computes the weather every week passed with varius computations defined by meteorologic functions. 
	  Runs on float vectors and is ram consuming!!!	  
ToDo: "Make writing and reading faster (right as now i am using fgets as the fastest method)
       Redevelop Resynthesis"
-------------------------------------------*/
#include <omp.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <sys/time.h>
#define intemp 22.0
#define inwind 0
#define pi 3.1415926
char filename[FILENAME_MAX];
int threads,frames,ysize,xsize;
int xsizeblock,ysizeblock;
int maxmemory;
int number_of_blocks=0,size_of_blocks=0,blocky=0,extramemory=0;
float pe;
float ****data;

//----Get true System memory ------ // Portable 
int get_system_memory()
{
   char *cmd="awk '{ if(NR==2){print $2}}' /proc/meminfo";//nice file!!!
   FILE *cmdfile=popen(cmd,"r");
   char result[256]={0x0};
   while(fgets(result,sizeof(result),cmdfile)!=NULL) 
   {
       printf("Detected %d kb or %d mb Available System Memory\n",atoi(result),atoi(result)/1024);
   }   
   pclose(cmdfile);   
   return(atoi(result));//warning fixed atoi
}
//---End of get true System memory ----------------------------//

//--------------------INITIALIZATION OF VECTORS--------------//
int initialize_vectors(){      
     data= malloc(2 * sizeof(float ***)); 
     int i,k,l;
     for (i=0;i<2;i++){	
	  data[i] = malloc(xsize * sizeof(float **));       
	  for (k=0;k<xsize;k++){	    
		data[i][k]=malloc(ysize * sizeof(float *));
		for (l=0;l<ysize;l++){
		      data[i][k][l]=malloc(3* sizeof(float));
		}	    
	   }    
      }
      return(1);     
}
//------------END OF INITIALIZATION OF VECTORS--------------------//

//--------------------INITIALIZATION OF VECTORS For Blocks!!!!--------------//
int initialize_vectorsblock(){ 
     printf("Initializing Block Vectors ->");
     data= malloc(2 * sizeof(float ***)); 
     int i,k,l;
     for (i=0;i<2;i++){	
	  data[i] = malloc(xsize * sizeof(float **));       
	  for (k=0;k<xsize;k++){	    
		data[i][k]=malloc((blocky+2) * sizeof(float *)); //Blocky +2 for 2 lines overlapping
		for (l=0;l<(blocky+2);l++){
			data[i][k][l]=malloc(3* sizeof(float));
		}	    
	  }    
     }
     printf("[OK]\n");
     return(1);     
}
//------------END OF INITIALIZATION OF VECTORS--------------------//

//-----------Start Of function REsynthesys-----------------------//Redevelop with bigger buffers!!!!!!
int resynthesis(int f){
    int i,x,y,b,lines;
    FILE *fpout; 
    FILE *fpin; 
    char temp,c;
    char output_filename[FILENAME_MAX];
    char input_filename[FILENAME_MAX];
    printf("Resynthesizing Frame #%d ->",f);
   
	sprintf(output_filename, "%s_Resynthesized_Frame_%d.mdf",filename,f);
	fpout = fopen (output_filename,"w" ) ;
	for (b=1;b<=number_of_blocks;b++){
	      sprintf(input_filename, "%s_frame_%d.framgment_%d", filename,f,b);
	      if (b==1)
	      {
		  lines=0;
		  //printf("First block opening file:%s\n",input_filename);
		  fpin = fopen (input_filename,"r" ) ;
		  if( fpin == NULL )  {
		      puts ("cannot open file") ;
		      exit(0) ;
		  }      
		  while ((c = fgetc(fpin)) != EOF){			
			if (c=='\n'){
			    lines++;
			}			
			//fprintf(stdout, "%c", c);			
			if (lines<blocky){
			    fprintf(fpout,"%c",c );      
			}  
		  }		  
		  fclose(fpin);
		  remove(input_filename);
		  //printf("numberof lines %d\n",lines);
	      }	else if (b==number_of_blocks){
		  lines=0;
		  //printf("Last block opening file:%s\n",input_filename);
		  fpin = fopen (input_filename,"r" ) ;		  
		  if( fpin == NULL )  {
		      puts ("cannot open file") ;
		      exit(0) ;
		  }	
		  while ((c = fgetc(fpin)) != EOF){			  
			  if (c=='\n'){
			      lines++;
			  }			  
			 // fprintf(stdout, "%c", c);
			  if (lines>1){
			      fprintf(fpout,"%c",c );
 			  }   
		  }		  
		  fclose(fpin);
		  remove(input_filename);
		  //printf("numberof lines %d\n",lines); 
	      } else{
		   lines=0;     
		   //printf("Medium block opening file:%s\n",input_filename);
		   fpin = fopen (input_filename,"r" ) ;
		    if( fpin == NULL )  {
			  puts ("cannot open file") ;
			  exit(0) ;
		    }		
		    while ((c = fgetc(fpin)) != EOF){
			  if (c=='\n'){
			      lines++;
			  }
			  //fprintf(stdout, "%c", c);
			  if ((lines>1)&&lines<(blocky+2)){
				fprintf(fpout,"%c",c );      
			  }    
		    }
		    fclose(fpin);
		    remove(input_filename);
		   // printf("numberof lines %d\n",lines); 
		}    
	}
	fclose(fpout);	
    
     printf("[OK]\n",output_filename);
    return(1);
   
}
//------------End Of REsysnthesys----------//


///////////FILE READING In Blocks///////////////////
int readthis(int frame_files){
     
      char *tel;
      tel=malloc((xsize*6+1)*sizeof(char));//bufer for reading !!! gets for speed!!!!
      char map;
      char mapf[3];
      FILE *fp ;
      int x,y,i,g,f;
    
     float ***temp;
     temp= malloc(xsize * sizeof(float **));//buffer for computing (overlapped)
     int mal,nal,yend;
     for (mal=0;mal<xsize;mal++){	
	  temp[mal] = malloc(2 * sizeof(float *));       
	  for (nal=0;nal<2;nal++){	
	      temp[mal][nal] = malloc(3 * sizeof(float));       
	  }
     }
     
      

for (frame_files=0;frame_files<frames;frame_files++){  //
  printf("-------------------- \nRendering Frame #%d |\n--------------------\n",frame_files+1);
  
//----------------------------This is for reading single value map files--------------------------------//
  if (frame_files==0){//If it is the first frame then the readen data will be in single format...... need to convert them .....
       int yend;
            
      printf("Opening File #%d ->",frame_files);
      fp = fopen (filename,"r" ) ;
      if( fp == NULL )  {
	  puts ("cannot open file") ;
	  exit(0) ;
      }
      printf("[OK]\nFragmenting File into #%d Segments and formating...\n",number_of_blocks);
      
      for (i=0;i<number_of_blocks;i++){
	    printf("Reading Segment #%d ->",i);
	    x=0;
	    y=0;
	    if (i+1==number_of_blocks){	  
		
		yend=(xsize*ysize-blocky*xsize*i)/xsize;
		//printf("Last Block\n");
		//case of last block 
		// printf("%d\n",(xsize*ysize-blocky*xsize*i)/xsize);
	        for(g=0;g<xsize;g++){//Copy of old....
		     data[0][g][0][0]=temp[g][0][0];//quick conversion ;-)
		     data[0][g][1][0]=temp[g][1][0];//quick conversion ;-)
		}
		for (y=0; y <yend;y++)
		{	
		      // printf("%d %d %d\n",x,y,i);
		      //printf("|");
		      for (x=0; x < xsize;x++){      
			    map= fgetc(fp) ;
			
			    if ( (map== EOF)||(map-48<0)||(map-48>5) ){//second check if file is shorter that defined ;-(
				  printf("\nERROR!!! EOF character found at position:%d\nCoppupted data!!! Exiting....\n",(x+1)*(y+1));//difining the position where the eof char was found
				  free(data);
				  free(temp);
				  exit(0);
			    }
			    else{				  
				  data[0][x][y+2][0]=(float)(map-48);//quick conversion ;-)
				 //printf("%f ",data[0][x][y][0]);
			    }
      
		      }    
		      // printf("|\n");    
		}   
	    }else if (i==0){    
		//case of all blocks  
		for (y=0; y < blocky;y++)
		{	
		//  printf("%d %d %d\n",x,y,i);
			// printf("|");
		      for (x=0; x < xsize;x++){      
			      map= fgetc(fp) ;
	
			      if ( (map== EOF)||(map-48<0)||(map-48>5) ){//second check if file is shorter that defined ;-(
				    printf("\nERROR!!! EOF character found at position:%d\nCoppupted data!!! Exiting....\n",(x+1)*(y+1));//difining the position where the eof char was found
				    free(data);
				    free(temp);
				    exit(0);
			      }
			      else{ 	
				  data[0][x][y][0]=(float)(map-48);//quick conversion ;-)
				  //printf("%f ",data[0][x][y][0]);
				  if (y==(blocky-2)){
					temp[x][0][0]= data[0][x][y][0];
				  }
				  if (y==(blocky-1)){
					temp[x][1][0]= data[0][x][y][0];	  
				  }	
			      }
		      }    
		      // printf("|\n");    
		}  
	    }else {   
	      
	//---------------	MEdium block------------Pay attention!!!!!!!!!!!!!!!!!
	     for (g=0;g<xsize;g++){	//Copy old			    
		data[0][g][0][0]=temp[g][0][0];//quick conversion ;-)
		data[0][g][1][0]=temp[g][1][0];//quick conversion ;-)
	     }			
	     for (y=0; y <blocky;y++)
		{	
		//  printf("%d %d %d\n",x,y,i);
		      //printf("|");
		      for (x=0; x < xsize;x++){      
			    map= fgetc(fp) ;
		
			    if ( (map== EOF)||(map-48<0)||(map-48>5) ){//second check if file is shorter that defined ;-(
				  printf("\nERROR!!! EOF character found at position:%d\nCoppupted data!!! Exiting....\n",(x+1)*(y+1));//difining the position where the eof char was found
				  free(data);
				  free(temp);
				  exit(0);
			    }
			    else{
				  	  
				  data[0][x][y+2][0]=(float)(map-48);//quick conversion ;-)
				  //printf("%f ",data[0][x][y][0]);
				  if (y==(blocky-2)){
					temp[x][0][0]=data[0][x][y+2][0];
				  }
				  if (y==(blocky-1)){
					temp[x][1][0]=data[0][x][y+2][0];	  
				  }	
				  
			    }
      
		      }    
		      // printf("|\n");    
		}   
	    }  
	    printf("[OK]\n");
	    if (i==0) {	      
		  //printf("(First Block)\n");
		 // printf("Ended with x %d,y %d\n",x,y);
		  initialize_data(x,y+2);
		  meteo(x,y,1,i+1,1,frame_files+1);	    
	    }else if (i+1==number_of_blocks){
		 // printf("(Last Block)\n");
		 // printf("Ended with x %d,y %d\n",x,y);
		 // initialize_data(x,y+2); Den xreiazetai giati ginetai mia kai megali fora.... 
		
		  meteo(x,y+2,1,i+1,1,frame_files+1); 
	    }else{
		  //printf("(Medium Block)\n");
		 // printf("Ended with x %d,y %d\n",x,y);
		  //initialize_data(x,y+2);
		  meteo(x,y+2,1,i+1,1,frame_files+1); 
	    }    
      }  
      //printf("---------------------------\n");
     // puts("-----------EOF-------------");
      //printf("---------------------------\n");
      fclose(fp);      
//     -------End of this part of reading (from simple file ------
      
//      Part where conversion of initial data reading and data output  from meteo reading is converted
   }else{//only after the first file......
  
      
     char output_filename[FILENAME_MAX];
     sprintf(output_filename, "%s_Resynthesized_Frame_%d.mdf",filename,frame_files);
     printf("Opening Resynthesized File #%d ->",frame_files);
      fp = fopen (output_filename,"r" ) ;
      if( fp == NULL )  {
	  puts ("cannot open file") ;
	  exit(0) ;
      }
      printf("[OK]\nFragmenting File into #%d Segments and Formating...\n",number_of_blocks);
        char ccc[sizeof(frames)+8];
	    fgets(ccc,sizeof(frames)+8,fp);//Escaping first line wjitch is the header (etc frame 1 ) in the outpout format as defined by read file function
	    //printf("\nHeader: %s",ccc);
	    
      for (i=0;i<number_of_blocks;i++){
	    int a,m;
	  
	    printf("Reading Segment #%d ->",i);
	    	    
	    if (i+1==number_of_blocks){	     
	     yend=(xsize*ysize-blocky*xsize*i)/xsize;
		//printf("Last Block\n");
		//case of last block 
		// printf("%d\n",(xsize*ysize-blocky*xsize*i)/xsize);
	        for(g=0;g<xsize;g++){//Copy of old....
		  for(a=0;a<3;a++){
		     data[0][g][0][a]=temp[g][0][a];//quick conversion ;-) Take only two copied lines
		     data[0][g][1][a]=temp[g][1][a];//quick conversion ;-)
		  }
		}
		for (y=0; y <yend;y++)
		{	
		      
		      // printf("%d %d %d\n",x,y,i);
		      //printf("|");
		     fgets(tel,(xsize*6)+1,fp);
		     //printf("\n|-%s\n",tel);m
// 		     #pragma omp parallel for private (x,mapf) 
		      for (x=0; x < xsize;x++){      
			for (m=0;m<3;m++){
			  for (a=0;a<2;a++){
			     mapf[a]=tel[(x*6)+m*2+a];
			     
			     //mapf[a]= fgetc(fp) ;			        
			      if ( (mapf[a]== EOF)||(mapf[a]-48<0)||(mapf[a]-48>9) ){//second check if file is shorter that defined ;-((
				  printf("\nERROR!!! Illigal character found at position x:%d y:%d %c\nCoppupted data!!! Exiting....\n ",x,y,mapf[a]);//difining the position where the eof char was found
				  free(data);
				  free(temp);
				  exit(0);
			      }
			  }
			  mapf[2]='\0';//for working atoi
			  //printf("\n|-%s\n",mapf);
			  data[0][x][y+2][m]=atoi(mapf);//quick conversion ;-)
			  
			  //printf(" %.2d:",(int)data[0][x][y][m]);
			  
		      }   
		    }
		    fgetc(fp);
		     //  printf("\n");    
		}   
	    }else if (i==0){    
		//case of first blocks  
		for (y=0; y < blocky;y++)
		{	
		//  printf("%d %d %d\n",x,y,i);
			// printf("|");
			fgets(tel,(xsize*6)+1,fp);
// 		      #pragma omp parallel for private (x,mapf) 
		      for (x=0; x < xsize;x++){      
			 for (m=0;m<3;m++){
			    for (a=0;a<2;a++){
			      mapf[a]=tel[(x*6)+m*2+a];
			     // mapf[a]= fgetc(fp) ;
			      //printf("%c",mapf[a]);
			      if ( (mapf[a]== EOF)||(mapf[a]-48<0)||(mapf[a]-48>9) ){//second check if file is shorter that defined ;-(
				    printf("\nERROR!!! Illigal character found at position x:%d y:%d %c\nCoppupted data!!! Exiting....\n",x,y,mapf[a]);//difining the position where the eof char was found
				    free(data);
				    free(temp);
				    exit(0);
			      }
			    }
			    mapf[2]='\0';
		            //printf("%.2d",atoi(mapf));
			    data[0][x][y][m]=(float)atoi(mapf);//quick conversion ;-)
			    //printf(" %.2d ",(int)data[0][x][y][m]);
			    if (y==(blocky-2)){
			        temp[x][0][m]=data[0][x][y][m];
		            }
			    if (y==(blocky-1)){
				temp[x][1][m]=data[0][x][y][m];	  
			    }			   
		      }		         
		}
		fgetc(fp);   //take the enter character
		  //printf("\n");
	      }
	    }else {   
	      
	//---------------	MEdium block------------Pay attention!!!!!!!!!!!!!!!!!
	     for(g=0;g<xsize;g++){//Copy of old....
		  for(a=0;a<3;a++){
		     data[0][g][0][a]=temp[g][0][a];//quick conversion ;-) Take only two copied lines
		     data[0][g][1][a]=temp[g][1][a];//quick conversion ;-)
		  }
		}
	     for (y=0; y <blocky;y++)
		{	
		//  printf("%d %d %d\n",x,y,i);
		      //printf("|");
		      fgets(tel,(xsize*6)+1,fp);
// 		      #pragma omp parallel for private (x,mapf) 
		      for (x=0; x < xsize;x++){      
		        for (m=0;m<3;m++){
		          for (a=0;a<2;a++){ 
			    mapf[a]=tel[(x*6)+m*2+a]; 
			    if ( (mapf[a]== EOF)||(mapf[a]-48<0)||(mapf[a]-48>9) ){//second check if file is shorter that defined ;-(
				  printf("\nERROR!!! Illigal character found at position x:%d y:%d %c\nCoppupted data!!! Exiting....\n",x,y,mapf[a]);//difining the position where the eof char was found
				  free(data);
				  free(temp);
				  exit(0);				
			    }
			  }
			  mapf[2]='\0';//ending map as string for atoi to work
			  data[0][x][y+2][m]=(float)atoi(mapf);//quick conversion ;-)
			  //printf(" %.2d ",(int)data[0][x][y][m]);
			  if (y==(blocky-2)){
				temp[x][0][m]=data[0][x][y+2][m];
			  }
			  if (y==(blocky-1)){
			    temp[x][1][m]=data[0][x][y+2][m];	  
			  }			         
		    }
		 }
		 fgetc(fp);   //take the enter character
		       //printf("\n");    
		}   
	    }  
	    printf("[OK]\n"); // Edw na mpoyne ta sections ..... apo to omp
	    if (i==0) {	      
		 // printf("(First Block)\n");
		 //printf("Ended with x %d,y %d\n",x,y);
		  //initialize_data(x,y);
		  meteo(x,y,1,i+1,1,frame_files+1);	    
	    }else if (i+1==number_of_blocks){
		 //printf("(Last Block)\n");
		// printf("Ended with x %d,y %d\n",x,y);
		 // initialize_data(x,y+2);
		  meteo(x,y+2,1,i+1,1,frame_files+1); 
	    }else{
		 // printf("(Medium Block)\n");
		 //printf("Ended with x %d,y %d\n",x,y);
		  //initialize_data(x,y+2);
		  meteo(x,y+2,1,i+1,1,frame_files+1); 
	    }    
      }  
      //printf("---------------------------\n");
     // puts("-----------EOF-------------");
      //printf("---------------------------\n");
      fclose(fp);     
   }
   resynthesis(frame_files+1);
 }
 free(temp);
}
////-------------------END OF FILE READING----------------
//------inblocks

///////////FILE READING/////////////////// Simple
int readfile(){

      char map; 
      FILE *fp ;
      int x,y;
      int count;
      printf("Opening File ->");
      fp = fopen (filename,"r" ) ;
      if( fp == NULL )  {
	  puts ("cannot open file") ;
	  exit(0) ;
      }
      printf("[OK]\n");
      printf("Reading file and formating ->");
      count=0;
      for (y=0; y < ysize;y++)
      {	
	  //printf("|");
	    for (x=0; x < xsize;x++){      
		  map= fgetc(fp) ;
		  count++;
		  if ( (map== EOF)||(map-48<0)||(map-48>5) ){//second check if file is shorter that defined ;-(
			printf("\nERROR!!! EOF character found at position:x:%d y:%d\n Coppupted data!!! Exiting....\n",x,y);//difining the position where the eof char was found
			free(data);
			exit(0);
			
		  }else{
			data[0][x][y][0]=(float)(map-48);//quick conversion ;-)
			//printf("%f ",data[0][x][y][0]);	
		  }
	    }    
	    //printf("|\n");    
      }
      //printf("---------------------------\n");
      puts("[OK]\n");
      //printf("---------------------------\n");
      fclose(fp);
      return(count);
}
////------------END OF FILE READING--------Simple file reading--------------------//

/*----------------------------------------------------------------------------------------/ 
-----------------------------------------DUMPING TO FILE -------------------------------*/
int dumptofile(int nfile, int t,int xs,int ys,int type,int fragment,int frame_number){  
    FILE *fp;   
    int x,y,a,i;  
    char output_filename [ FILENAME_MAX ];
    if (type==0){
	  sprintf(output_filename, "%s_frame_%d.mdf", filename, nfile);
    }else {
	  sprintf(output_filename, "%s_frame_%d.framgment_%d", filename, frame_number,fragment);
    }
   // printf("filename = \"%s\"\nand xs,ys: %d %d\n", output_filename,xs,ys);
    fp = fopen (output_filename,"w" ) ;
    if (fp==NULL){
	  printf("Error\n\n");
	  exit(1);
    }    
   // if (type==0){
	  printf("Writing to File ->",output_filename);  
   // }
    if (type==0)fprintf(fp,"Frame %d\n",nfile);
    if (type==1)fprintf(fp,"Frame %d\n",frame_number);
    for (y=0;y<ys;y++){
          for (x=0;x<xs;x++){	      
		      fprintf(fp,"%.2d%.2d%.2d",(int)round((data[t][x][y][0])),(int)round((data[t][x][y][1])),(int)round((data[t][x][y][2]))); //opwsdhpote round giati etsi to zitisate..... exw peiraksei kai to presicion !!!!	        
	  }
          fprintf(fp,"\n");
     }
     fprintf(fp,"\n");
     fclose(fp);
	 //TGA WRITE
	 TGABuffer = (char *)malloc(SAMPLESPERPIXEL * ys * xs * sizeof(char));
	 for (y=0;y<ys;y++){
          for (x=0;x<xs;x++){	
			if ((int)round((data[t][x][y][0])) == 5) {
				TGABuffer[j]     = 0;
				TGABuffer[j + 1] = (int)round((data[t][x][y][1]));
				TGABuffer[j + 2] = (int)round((data[t][x][y][1]));
			} else if ((int)round((data[t][x][y][0])) == 4) {
				TGABuffer[j]     = (int)round((data[t][x][y][0]))*16;								/* 0x0000 to 0x007E 	*/
				TGABuffer[j + 1] = (int)round((data[t][x][y][1]))*16;
				TGABuffer[j + 2] = (int)round((data[t][x][y][2]))*16;
			} else if ((int)round((data[t][x][y][0])) == 3) {
				TGABuffer[j]     = (int)round((data[t][x][y][0]))*32;								/* 0x0000 to 0x007E 	*/
				TGABuffer[j + 1] = (int)round((data[t][x][y][1]))*32;
				TGABuffer[j + 2] = (int)round((data[t][x][y][2]))*32;
			} else if ((int)round((data[t][x][y][0])) == 2) {
				TGABuffer[j]     = (int)round((data[t][x][y][0]))*64;								/* 0x0000 to 0x007E 	*/
				TGABuffer[j + 1] = (int)round((data[t][x][y][1]))*64;
				TGABuffer[j + 2] = (int)round((data[t][x][y][2]))*64;
			} else if ((int)round((data[t][x][y][0])) == 1) {
				TGABuffer[j]     = (int)round((data[t][x][y][0]))*200;								/* 0x0000 to 0x007E 	*/
				TGABuffer[j + 1] = (int)round((data[t][x][y][1]))*200;
				TGABuffer[j + 2] = (int)round((data[t][x][y][2]))*200;
			} else if ((int)round((data[t][x][y][0])) == 0) {
				TGABuffer[j]     = 0;
				TGABuffer[j + 1] = 255;
				TGABuffer[j + 2] = 255;
			} else {
				TGABuffer[j]     = 0;
				TGABuffer[j + 1] = 0;
				TGABuffer[j + 2] = 0;
			}
		}
	 }
	 
		FILE		*OutputFile;
		sprintf(OutputFile, "%s-.tga", nfile);
	 
		fputc(0, OutputFile);
		fputc(0, OutputFile);
		fputc(2, OutputFile);		/* uncompressed RGB */
		fputc(0, OutputFile);
		fputc(0, OutputFile);
		fputc(0, OutputFile);
		fputc(0, OutputFile);
		fputc(0, OutputFile);
		fputc(0, OutputFile);
		fputc(0, OutputFile);		/* X origin */
		fputc(0, OutputFile);
		fputc(0, OutputFile);		/* Y origin */
		fputc((xpixels & 0x00FF), OutputFile);
		fputc((xpixels & 0xFF00) / 256, OutputFile);
		fputc((ypixels & 0x00FF), OutputFile);
		fputc((ypixels & 0xFF00) / 256, OutputFile);
		fputc(24, OutputFile);		/* 24 bit bitmap */
		fputc(0x20, OutputFile);

		fwrite(TGABuffer, sizeof(char), SAMPLESPERPIXEL * ys * xs, OutputFile);

		fclose(OutputFile);
	 
	 //TGA END
	 
	 
     printf("[OK]\n");
	 
}
//--------------End of Dumping to File--------------------------------------------///

//--------------Initializing Data (writing the missing values ---wind temp ----)//////
int initialize_data(int xs,int ys){ 
    int thread,x,y; 
    printf("Initializing Meteo Data ->");
    //Going into parallel  for best performance !!! simple for not big files ...... 
    #pragma omp parallel for private(x)
    for (y=0; y < ys;y++){	
	  //printf("|*");
	 for (x=0; x < xs;x++)
	 {	//printf( "|K|:%d ",(int)data[0][x][y][0]);
	        data[0][x][y][1]=intemp; // write the initialization temps 
	        data[0][x][y][2]=inwind; // write the initialization temps 
	        //printf( "C:%d ",(int)data[0][x][y][1]);
	       // printf( "W:%d ",(int)data[0][x][y][2]);	      
	 }
  // printf("|\n");
    } 
    puts("[OK]");  
}
//End of initialization of local data!!!-----------------//

/*-----------------------------------------------------------------------------------/
---------------------------------Meteo Function ------------------------------------*/
//----------------------MEteo COmputation--------------------------------------------------////////////////
int meteo(int xs,int ys,int mode,int fragment,int frames_to_render,int frame_file){
    struct timeval	StartTime, EndTime;
    int t,tn,x,y,k,kn,i,j,a,b,thread,frame,ba;    
    int count[3];    
    float temp[3];
   
    printf("Calculations for %d iterations ->",xs*ys*3);  
    x=0;//itialize for proper use
    y=0;
    t=1;
    tn=0;
    //int chunk=(ysize/threads);    
    for (frame=1; frame <= frames_to_render;frame++){  
	   gettimeofday(&StartTime, NULL);
	  ba=t;//Extract pointer to next t
	  t=tn;
	  tn=ba;
	  //printf("\n-----------------------\nRendering Frame:    %d |\n-----------------------\n",frame);
	  // printf("\n-------------------------------\n|%d | chunk: %d t:%d tn:%d,mod%d:|\n-------------------------------\n\n",frame,chunk,t,tn,(frame%2));    
	  float new=0; 
	  //#pragma omp for schedule(dynamic,chunk) nowait  private(x,a,count,i,j,temp,y)   
	  #pragma omp parallel for  private(i,j,count,temp,a,x,new)
	  for (y=0; y < ys;y++)
	  {		
		for (x=0; x<xs;x++){	  
		      //----------------------Main Functions and calulations---------------------------///   
		      //erwthshh pws mporw na kanw % xwris int?
		      data[tn][x][y][0]=((int)((data[t][x][y][0])+((sin(7*(frame-1)*pi/180))*3)))%6; //all ok !!!!! go go go problem solved -lm in gcc *remind this is for next situtation	 
		      data[tn][x][y][1]=22+(sin(6.5*(frame-1)*pi/180))*10-(data[t][x][y][0]/4)+(data[t][x][y][1]/50);//go go go (frame-1 0) 1...  proc inside calculation
		      data[tn][x][y][2]=(data[t][x][y][2]/4)+((sin(7*(frame-1)*pi/180))*3);	  
		      //printf("--------------Locked-----------\n|K*=%d T*=%f W*=%f* t=%d|",(int)data[tn][x][y][0],data[tn][x][y][1],data[tn][x][y][2],frame);	
		      //--------------------------End of main functions -------------------------------//	  
		      //--------------------------Going into rounding ----------------// it works great!!!!
		      count[0]=0;
		      count[1]=0;
		      count[2]=0;
		      temp[0]=0;
		      temp[1]=0;
		      temp[2]=0;
		      a=0;
		      //printf("\n|Rounding pixels for %d,%d in frame: %d witch has K:%f and Kn:%f|\n",y,x,tn,data[t][x][y][0],data[tn][x][y][0]);	  
		      for (i=-1;i <=1;i++){	
			    for (j=-1;j<=1;j++){		
				  if (((x+j)>=0)&&((y+i)>=0)&&((x+j)<xs)&&((y+i)<ys)){//physical border
				  //	printf(" [%f] ",data[t][x+j][y+i][0]); 			
					for (a=0;a<3;a++){ //where [a] every time will be the K,C,W    		   
					      count[a]++;
					      // if(y>=199)printf("%d,%d,%d\n",y+i,x+j,a);
					      temp[a]=temp[a]+data[t][x+j][y+i][a];//calculate sum of all near values 
					}		 
				  }	   
			    }	        
			    // printf("\n");	 
		      }
		      //	printf("---------------------\nSUM =%f and count=%d\n",temp[0],count[0]); 
		      for (a=0;a<3;a++){ //Calculating the average	  
			    new=data[tn][x][y][a];
			    // printf("tn= %f\n",new);
			    data[tn][x][y][a]=(temp[a]+data[tn][x][y][a])/(count[a]+1);
			    // printf("*\n\nOK4\n %d %d %d %d",y-1,x-1,t-1,a-1); aksioperiergo 		    
		      }
		      //-------------------------done with rounding-------------------------//	  
		      // printf("\n---- Nnew K %f----------\n------------------------------\n\n",data[tn][x][y][0]);
		} 	
		//printf("\n");	    
	  }
	  //pragma end     
	   gettimeofday(&EndTime, NULL);
	   if (EndTime.tv_usec < StartTime.tv_usec) {
		    int nsec = (StartTime.tv_usec - EndTime.tv_usec) / 1000000 + 1;
		    StartTime.tv_usec -= 1000000 * nsec;
		    StartTime.tv_sec += nsec;
           }
	   if (EndTime.tv_usec - StartTime.tv_usec > 1000000) {
		    int nsec = (EndTime.tv_usec - StartTime.tv_usec) / 1000000;
		    StartTime.tv_usec += 1000000 * nsec;
		    StartTime.tv_sec -= nsec;
           }
	   printf(" %ld.%.6ld sec-> ", EndTime.tv_sec  - StartTime.tv_sec, EndTime.tv_usec - StartTime.tv_usec);	
	   printf ("[OK]\n");
	  dumptofile(frame,tn,xs,ys,mode,fragment,frame_file); // and dump it to a file
	 
	  //printf("Dump : frame: %d,x: %d, y: %d ,mode : %d\n",frame,xs,ys,mode);	
    }//end of frame
   
   
}
/////-------------------------------END OF METEO FUNCTION --------------------------------------------/////////////////

/*----------------------------------------------------------
/*---------------------End of All Functions----------------- 
----------------------GOing to main part--------------------
------------------------------------------------------------*/

//-------------------------MAIN FUNCTION ---------------------------------//
main (){     
	struct timeval	StartTime, EndTime;
	int maxmem,systemem;
	char choise[3];
	printf("\n---------Welcome to Meteo---------\nInteger size: %d\nFloat Size: %d\n",sizeof(int),sizeof(float));  
	printf("Please enter X-size (default:8) :");
	scanf("%d",&xsize);
	if (xsize==0){
	    xsize=8;
	}
	printf("->X-size:%d -> [OK]\n",xsize);
	printf("Please enter Y-size (default:8) :");
	scanf("%d",&ysize);
	if (ysize==0){
	    ysize=8;
	}
	printf("->Y-size:%d -> [OK]\n",ysize);  
	systemem=get_system_memory();
	//printf("%d",systemem);
	printf("Please enter Max Memory to use in Kbytes (0=all):");
	scanf("%d",&maxmem);
	if (maxmem==0){
	    maxmem=systemem;
	}
	printf("->Maxmem is: %d Bytes or %d Mbytes\n",maxmem*1024,maxmem/1024);          
 	//maxmemory=(maxmem)/(sizeof(float)*3*2);
	//maxmemory=(maxmem*1024)/(sizeof(float)*3*2)-(xsize*2); // total memory used - 2 overlaped lines and -10 used integers and chars
	maxmemory=(maxmem*1024)/(sizeof(float)*3*2); // total memory used - 2 overlaped lines and -10 used integers and chars
	printf("->Maxmem can hold up to %d Float Elements\n",maxmemory);        
		printf("Please enter input filename:");
	scanf("%s",filename);
	if (strcmp(filename,"0")==0){
	    sprintf(filename,"./plainmap.dat");
	}
	printf("->File to open: %s -> [OK]\n",filename); 
	printf("Please enter number of Frames to render (default:1) :");
	scanf("%d",&frames);
	if (frames==0){
	    frames=1;
	}
	printf("->Frames:%d -> [OK]\n",frames);
	int proccesors;
	proccesors=omp_get_num_procs();
	printf("Detected %d available proccesors\n",proccesors);
	printf("Please enter number of threads:");
	scanf("%d",&threads);
	if (threads==0){
	    threads=1;
	}
	printf("->Threads:%d -> [OK]\n",threads);
	omp_set_num_threads(threads);
//The test case 
	if (xsize*ysize>=maxmemory){   
	    
	    printf("\n------------Warning file is Very Large!-------------------\nFilesize: %dx%d = %d Bytes\nMaxmemory after alteration for Float Vectors: %d Elements\n",xsize,ysize,ysize*xsize,maxmemory);
	    printf(" \nInput Has a total of: %d Float Elements\n",xsize*ysize,xsize*ysize);
	    printf("Maxmem:%d Float Elements\n",maxmemory);  
	    extramemory=(ysize*xsize)-(maxmemory);
	    printf("Extra memory: %d Float Elements\n",extramemory);
	    blocky=(int)maxmemory/xsize;
	    if (blocky<4){
		printf("Warning not enough memory to run .... abording/\n");
		exit(0);
	    }
	    size_of_blocks=xsize*blocky;
	    pe=((float)ysize/blocky)-((int)ysize/blocky);       
	    if (pe>0)number_of_blocks=((int)(ysize/blocky))+1;
	    else number_of_blocks=ysize/blocky; // or ysize*xsize/size_of_blocks
	    printf("Number of lines in memoryblock=%d\nWill be using memory block size of:%d Float Elements\nNumber of blocks to use:%d  \nYsize/lines:%f  expo:%f\n",blocky,size_of_blocks,number_of_blocks,(float)ysize/blocky,pe);	    
	    printf("Are you sure? This can take a lot of time...? (yes/no):");
	    scanf("%s",choise);
	    if (!strcmp(choise,"no")){
	      printf("Try Upgrading System's Memory!!!\nImidiately\n");
		  exit(0);
	    }
	    
	    //frames=1;//Quick Disable Meteo function for going multiframe
	    gettimeofday(&StartTime, NULL);
	    initialize_vectorsblock();
	    readthis(frames);
	    free(data);
	    gettimeofday(&EndTime, NULL);
	    if (EndTime.tv_usec < StartTime.tv_usec) {
		int nsec = (StartTime.tv_usec - EndTime.tv_usec) / 1000000 + 1;
		StartTime.tv_usec -= 1000000 * nsec;
		StartTime.tv_sec += nsec;
	    }
	    if (EndTime.tv_usec - StartTime.tv_usec > 1000000) {
		int nsec = (EndTime.tv_usec - StartTime.tv_usec) / 1000000;
		StartTime.tv_usec += 1000000 * nsec;
		StartTime.tv_sec -= nsec;
	    }
	    printf("Tatal Calculation time for Fragmented Data: [%ld.%.6ld] seconds\n", EndTime.tv_sec  - StartTime.tv_sec, EndTime.tv_usec - StartTime.tv_usec);
	    	    
	    }else{    
		printf("Please Wait initializing Vectors.....This can take some time ->");
		int i;
		i=initialize_vectors();
	   
		if (!i){
		    printf("Oups this souldn't happen\n");
		    exit(0);
		}		       
		printf("[OK]\n");
		int read;         
		read= readfile();
		printf("Bytes read:%d -> [OK]\n",read);    
		//sleep(1);  
		gettimeofday(&StartTime, NULL);
		initialize_data(xsize,ysize);
		//dumptofile(0,0); if you want to create a initial file
		meteo(xsize,ysize,0,0,frames,0);
		free(data);
		gettimeofday(&EndTime, NULL);
		if (EndTime.tv_usec < StartTime.tv_usec) {
		    int nsec = (StartTime.tv_usec - EndTime.tv_usec) / 1000000 + 1;
		    StartTime.tv_usec -= 1000000 * nsec;
		    StartTime.tv_sec += nsec;
		}
		if (EndTime.tv_usec - StartTime.tv_usec > 1000000) {
		    int nsec = (EndTime.tv_usec - StartTime.tv_usec) / 1000000;
		    StartTime.tv_usec += 1000000 * nsec;
		    StartTime.tv_sec -= nsec;
		}
		printf("Total Calculation time for Continious Data: [%ld.%.6ld seconds]\n", EndTime.tv_sec  - StartTime.tv_sec, EndTime.tv_usec - StartTime.tv_usec);
		
	  }	
	  printf("\n\n-----------------------------------------------\nMeteo Finised All Calculations Have a Nice Day|\n-----------------------------------------------\n\n");
	  exit(0);
}
